<?php

namespace app\api\logic;

use app\common\exception\BusinessException;
use app\common\model\AppConfig;
use think\file\UploadedFile;

class FileManage
{
    private $contentTypeDict = [
        "audio/mpeg" => "m4a",
        "audio/x-aac" => "acc",
        "image/png" => "png",
        "image/jpeg" => "jpg",
        "application/x-latex" => "latex",
        "image/gif" => "gif",
        "application/pdf" => "pdf",
        "application/msword" => "doc",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document" => "docx",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" => "xlsx",
    ];

    public function upload($app, UploadedFile $file)
    {
        try {
            $appId = getAppId();
            $config = app(AppConfig::class)->getByIdAndType($appId, 'file_server');

            // 获取文件信息
            $fileType = $file->getMime();

            // 计算文件的MD5哈希值
            $fileHash = strtolower($file->md5());

            // 根据hash生成二级目录
            $filePath1 = substr($fileHash, 0, 2);
            $filePath2 = substr($fileHash, 2, 2);

            // 创建所需的文件路径
            $fileServerRootPath = $config['save_path'];
            $fileServerHost = $config['domain'];
            $targetPath = DIRECTORY_SEPARATOR . $app . DIRECTORY_SEPARATOR . $filePath1 . DIRECTORY_SEPARATOR . $filePath2 . DIRECTORY_SEPARATOR;

            // 确保目录存在
            if (!file_exists($targetPath)) {
                if (!mkdir($targetPath, 0777, true)) {
                    throw new BusinessException("创建目录 {$targetPath} 失败");
                }
            }

            // 填充完整文件名称
            $extension = $this->getExtensionByContentType($fileType);
            $fillName = $fileHash . '.' . $extension;

            // 保存文件到指定目录
            $file->move($fileServerRootPath . $targetPath, $fillName);

            // 返回远程URL
            $remoteUrl = $fileServerHost . str_replace('\\', '/', $targetPath) . $fillName;
            return $remoteUrl;
        } catch (BusinessException $e) {
            throw new BusinessException("文件操作异常: " . $e->getMessage());
        }
    }

    /**
     * getExtensionByContentType
     * @param $fileType
     * @return string
     * @throws BusinessException
     */
    private function getExtensionByContentType($fileType): string
    {
        if (isset($this->contentTypeDict[$fileType])) {
            return $this->contentTypeDict[$fileType];
        }
        throw new BusinessException("暂不支持的文件类型:" . $fileType);
    }
}